package core;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Point2D;

import javax.swing.ImageIcon;

public abstract class Unit implements Drawable {
	
	protected Point2D.Double position;
	protected int viewAngle; // In degrees
	protected int health;
	protected Dimension size;
	protected ImageIcon image;
	protected Ellipse2D.Double bounds;
	protected final int maxHealth;
	
	/**
	 * @param position
	 * @param viewAngle
	 * @param health
	 * @param size
	 * @param image
	 */
	public Unit( Point2D.Double position, int health, ImageIcon image, Dimension size, int viewAngle )
	{
		this.position = position;
		this.viewAngle = viewAngle;
		this.health = health;
		this.size = size;
		this.image = image;
		this.maxHealth = health;
		
		if ( position != null )
			calcBounds();
	}
	
	public void calcBounds(){
		this.bounds = new Ellipse2D.Double( position.x, position.y, getSize().getWidth(), getSize().getHeight() );	
	}
	
	/**
	 * @return the health
	 */
	public int getHealth() {
		return health;
	}
	
	/**
	 * @param health the health to set
	 */
	public void setHealth(int health) {
		this.health = health;
	}
	
	/**
	 * @return the image
	 */
	public ImageIcon getImage() {
		return image;
	}

	/**
	 * @return the position
	 */
	public Point2D.Double getPosition() {
		return position;
	}
	
	/**
	 * @param position the position to set
	 */
	public void setPosition(Point2D.Double position) {
		this.position = position;
		
		calcBounds();
	}
	
	/**
	 * @return the size
	 */
	public Dimension getSize() {
		return size;
	}

	/**
	 * @return the view angle
	 */
	public int getViewAngle() {
		return viewAngle;
	}
	
	/**
	 * @param viewAngle
	 *            the view angle to set
	 */
	public void setViewAngle(int viewAngle) {
		this.viewAngle = viewAngle;
	}
	
	public boolean update() {
		calcBounds();
		
		return false;
	}
	
	public Ellipse2D.Double getBounds(){
		return this.bounds;
	}
	
	public void draw(Graphics g, Rectangle area, Component c) {		
		if ( !isOutsideView() ) {
			if ( viewAngle == 0 )
				g.drawImage(this.image.getImage(), (int)this.position.x, (int)this.position.y, c );
			else {
				Graphics2D g2d = (Graphics2D)g;
			    g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
		
			    AffineTransform oldForm = g2d.getTransform();
			    AffineTransform newForm = (AffineTransform) g2d.getTransform().clone();
			    
			    newForm.rotate(Math.toRadians(this.viewAngle), (int)getMiddle().x, (int)getMiddle().y);
			    
			    g2d.setTransform(newForm);
				g2d.drawImage(this.image.getImage(), (int)this.position.x, (int)this.position.y, c );
				g2d.setTransform(oldForm);
			}
		}
	}
	
	public Point2D.Double getMiddle()
	{
		return new Point2D.Double( this.position.x + getSize().getWidth() / 2, this.position.y + getSize().getHeight() / 2 );
	}
	
	/**
	 * Controleert of de unit niet meer het scherm te zien is (buiten het scherm valt)
	 * @return boolean
	 */
	public boolean isOutsideView()
	{
		int minPosX = 0 - getSize().width / 2;
		int minPosY = 0 - getSize().height / 2;
		
		int maxPosX = Model.battlefieldWidth + getSize().width / 2;
		int maxPosY = Model.battlefieldHeight + getSize().height / 2;
		
		return ( this.position.x < minPosX || this.position.y < minPosY | this.position.x > maxPosX || this.position.y > maxPosY );
	}

	/**
	 * @return the maxHealth
	 */
	public int getMaxHealth() {
		return maxHealth;
	}
	
	/**
	 * @return huidige health in 0-1
	 */
	public double getHealthPercentage() {
		return (double)health / (double)maxHealth;
	}
}
